package io.gitee.chearnee.fw.theadpool;

import com.alibaba.ttl.threadpool.TtlExecutors;
import io.gitee.chearnee.fw.theadpool.property.ThreadPoolProperties;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 2021/8/27 11:50
 */
@EnableAsync
@EnableConfigurationProperties(ThreadPoolProperties.class)
public class ThreadPoolTaskConfiguration {

  @Bean
  @Primary
  public ThreadPoolTaskExecutor taskExecutor(ThreadPoolProperties threadPoolProperties) {
    return buildThreadPoolTaskExecutor(threadPoolProperties.getThreadNamePrefix(), threadPoolProperties);
  }

  @ConditionalOnProperty(prefix = "fw.config.pool.ttl", value = "enabled", havingValue = "true", matchIfMissing = true)
  @Bean(name = "ttlTaskExecutor")
  public Executor ttlTaskExecutor(ThreadPoolProperties threadPoolProperties) {
    String threadNamePrefix = "TTL-fw-async-Service-";
    if (StringUtils.hasText(threadPoolProperties.getThreadNamePrefix())) {
      threadNamePrefix = "TTL-" + threadPoolProperties.getThreadNamePrefix();
    }
    ThreadPoolTaskExecutor executor = buildThreadPoolTaskExecutor(
            threadNamePrefix, threadPoolProperties);
    executor.setBeanName("ttlTaskExecutor");
    executor.initialize();
    return TtlExecutors.getTtlExecutor(executor);
  }

  private ThreadPoolTaskExecutor buildThreadPoolTaskExecutor(String threadNamePrefix, ThreadPoolProperties threadPoolProperties) {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
    executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
    executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
    executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveTime());
    executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy：由调用线程（提交任务的线程）处理该任务
    RejectedExecutionHandler rejectedExecutionHandler = BeanUtils
            .instantiateClass(threadPoolProperties
            .getRejectedExecutionHandler());
    executor.setRejectedExecutionHandler(rejectedExecutionHandler);
    return executor;
  }
}
